﻿#region LicenseHeader

// Copyright 2012 The Trustees of Indiana University.  All rights reserved.
// 
// The Indiana University licenses this file to you under the Apache License, 
// Version 2.0 (the "License"); you may not use this file except in compliance 
// with the License.  You may obtain a copy of the License at 
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
// See the License for the specific language governing permissions and 
// limitations under the License.
// 
// @author Thilina Gunarathne (tgunarat@indiana.edu)

#endregion

using System;
using System.Diagnostics;
using System.IO;
using Ionic.Zip;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;

namespace AzureMRCore.MapRed
{
    public class MapRedUtils
    {
        internal static string DownloadBLOB(string tempDir, CloudBlobClient blobClient, string jobID,
                                            string blobURI)
        {
            string localInputFileName;
            int retryCount = 0;
            DownloadRetryLabel:
            try
            {
                // move data to here
                CloudBlob fileBlob = blobClient.GetBlobReference(blobURI);
                DirectoryInfo dir =
                    Directory.CreateDirectory(tempDir);
                string[] parts = blobURI.Split('/');
                string fileName = parts[parts.Length - 1];
                localInputFileName = dir.FullName + "\\" + fileName;

                BlobRequestOptions options = new BlobRequestOptions();
                options.Timeout = new TimeSpan(0, 4, 0, 0);
                //fileBlob.DownloadToFile(localInputFileName, options);
                using (FileStream fs = new FileStream(localInputFileName, FileMode.Create))
                {
                    // I’m using an four-hour timeout
                    fileBlob.DownloadToStream(fs, options);
                }
            }
            catch (Exception e)
            {
                if (retryCount < 2)
                {
                    retryCount++;
                    Trace.WriteLine("retrying" + e);
                    goto DownloadRetryLabel;
                }
                throw;
            }

            return localInputFileName;
        }

        internal static Stream DownloadBLOBToStream(string tempDir, CloudBlobClient blobClient, string jobID,
                                                    string blobURI)
        {
            // move data to here
            CloudBlob fileBlob = blobClient.GetBlobReference(blobURI);

            MemoryStream stream = new MemoryStream(new byte[fileBlob.Properties.Length]);
            fileBlob.DownloadToStream(stream);
            return stream;
        }

        /* For distributed cache */

        public static DirectoryInfo DownloadAndExtract(CloudStorageAccount storageAccount, string blobURI,
                                                       string localFileName, string dirName)
        {
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            LocalResource localResource = RoleEnvironment.GetLocalResource("temp");

            CloudBlob fileBlob = blobClient.GetBlobReference(blobURI);
            DirectoryInfo dir = Directory.CreateDirectory(localResource.RootPath + "\\" + dirName);
            string localInputFileName = localResource.RootPath + "\\" + localFileName;

/*            using (FileStream fs = new FileStream(localInputFileName, FileMode.Create))
            {
                // I’m using a one-hour timeout
                fileBlob.DownloadToStream(fs, new BlobRequestOptions {Timeout = new TimeSpan(1, 0, 0)});
            }*/

            fileBlob.DownloadToFile(localInputFileName);


            //DirectoryInfo dir = System.IO.Directory.CreateDirectory(System.Environment.CurrentDirectory + "\\" + fileBlob.Container.Name);
            //fileBlob.DownloadToFile(dir.FullName + "\\" + localFileName);
            //inputFile = dir.FullName + "\\" + localInputFileName;
            //String file = "C:\\Users\\tgunarat\\temp\\128.zip";
            // string unpackDirectory = "db";
            using (ZipFile zip1 = ZipFile.Read(localInputFileName))
            {
                // here, we extract every entry, but we could extract conditionally
                // based on entry name, size, date, checkbox status, etc.  
                foreach (ZipEntry e in zip1)
                {
                    e.Extract(dir.FullName, ExtractExistingFileAction.OverwriteSilently);
                }
            }
            return dir;
        }
    }
}